package operator

import (
	"gitee.com/bupt-zkjc/fabric2.2-interface/entity"
	"strings"
)

type ChaincodeOperator struct {
	FabricOperator *FabricOperator
}

func (l *ChaincodeOperator) DeployChaincode(chain entity.Chain, channel entity.Channel, cc entity.Chaincode) (string, error) {

	fc := entity.ParseFabircChannelAndChaincodeWithOrg(entity.ParseFabircChannelWithOrg(chain, channel), cc)
	_, err:= l.FabricOperator.deployChaincode(fc)
	if err != nil {
		logger.Error(err)
		return "Deploy chaincode fail: ", err
	}

	logger.Info("SDK---Deploy chaincode success")
	return "Deploy chaincode success", nil
}

func (l *ChaincodeOperator) InitChaincode(chain entity.Chain, channel entity.Channel, cc entity.Chaincode) (
	string, error) {

	fc := entity.ParseFabircChannelAndChaincodeWithOrg(entity.ParseFabircChannelWithOrg(chain, channel), cc)
	args := make([][]byte, 0)

	for _, v := range strings.Split(cc.ArgsGm, ";") {
		args = append(args, []byte(v))
	}
	fc.ArgsGm = args
	resp, err := l.FabricOperator.initChaincode(fc)

	if err != nil {
		logger.Error(err)
		return "Init chaincode fail: ", err
	}
	logger.Info("SDK---Init Chaincode Success")
	return resp, nil
}

func (l *ChaincodeOperator) UpgradeChaincode(chain entity.Chain, channel entity.Channel, cc entity.Chaincode) (string, error) {

	fc := entity.ParseFabircChannelAndChaincodeWithOrg(entity.ParseFabircChannelWithOrg(chain, channel), cc)
	//args := make([][]byte, 1)
	////args[0] = []byte("init")
	//
	//for _, v := range strings.Split(cc.ArgsGm, ";") {
	//	args = append(args, []byte(v))
	//}
	//fc.ArgsGm = args

	_, err := l.FabricOperator.updateChaincode(fc)
	if err != nil {
		logger.Error(err.Error())
		return "Upgrade fail: ", err
	}
	logger.Info("SDK---Upgrade chaincode success")
	return "Upgrade chaincode success", nil
}

func (l *ChaincodeOperator) InvokeChaincode(chain entity.Chain, channel entity.Channel, cc entity.Chaincode) (string, error) {

	fc := entity.ParseFabircChannelAndChaincodeWithOrg(entity.ParseFabircChannelWithOrg(chain, channel), cc)
	args := make([][]byte, 0)

	for _, v := range strings.Split(cc.ArgsGm, ";") {
		args = append(args, []byte(v))
	}
	fc.ArgsGm = args
	resp, err := l.FabricOperator.invokeChaincode(fc)

	if err != nil {
		logger.Error(err.Error())
		return "Invoke fail: ", err
	}
	logger.Info("SDK---Invoke Chaincode Success")
	return resp, nil
}

func (l *ChaincodeOperator) QueryChaincode(chain entity.Chain, channel entity.Channel, cc entity.Chaincode) (string, error) {
	fc := entity.ParseFabircChannelAndChaincodeWithOrg(entity.ParseFabircChannelWithOrg(chain, channel), cc)
	args := make([][]byte, 0)

	for _, v := range strings.Split(cc.ArgsGm, ";") {
		args = append(args, []byte(v))
	}
	fc.ArgsGm = args
	resp, err := l.FabricOperator.queryChaincode(fc)
	if err != nil {
		logger.Error(err)
		return "Query fail", err
	}
	logger.Info("SDK---Query Chaincode Success")
	return resp, nil
}

func (l *ChaincodeOperator) QueryLedger(chain entity.Chain, channel entity.Channel) (interface{}, error) {

	fc := entity.ParseFabircChannelWithOrg(chain, channel)
	resp, err := l.FabricOperator.queryLedger(fc)
	if err != nil {
		logger.Error(err)
		return "Query fail: ", err
	}
	logger.Info("SDK---Query Ledger Success")
	return resp, nil
}